﻿# coding: utf-8

import wx
import wx.lib.colourselect as csel
import wx.lib.scrolledpanel as scrolled

import weakref

from wxFramework.CustomUI import wxColorPickButton

import ParticleEmitter

class wxPanelPropertyModifier(scrolled.ScrolledPanel):
    def __init__(self, parent, id):
        scrolled.ScrolledPanel.__init__(self, parent, id)
        
        self._staticModifierType = wx.StaticText(self, wx.NewId())        
        self._slider = wx.Slider(self, wx.NewId(), 2000, 0, 2000, style = wx.SL_HORIZONTAL|wx.SL_LABELS|wx.SL_AUTOTICKS|wx.SL_INVERSE)
        self._slider.SetTickFreq(100, 0)
        self._ticksWin = wx.Window(self, wx.NewId(), style = wx.SUNKEN_BORDER)
        size = self._ticksWin.GetClientSize()
        self._bmpBuffer = wx.EmptyBitmap(max(1, size.width), max(1, size.height))

        self._bnPreKeyFrame = wx.Button(self, wx.NewId(), 'Prev')
        self._bnNextKeyFrame = wx.Button(self, wx.NewId(), 'Next')
        self._bnSetKeyFrame = wx.Button(self, wx.NewId(), 'Set')
        self._bnRemoveKeyFrame = wx.Button(self, wx.NewId(), 'Remove')
        self._color = wxColorPickButton(self, wx.NewId(), '')
        self._editParam1 = wx.TextCtrl(self, wx.NewId(), '')
        self._editParam2 = wx.TextCtrl(self, wx.NewId(), '')
        self._editParam3 = wx.TextCtrl(self, wx.NewId(), '')
        
        sizerKeyFrame = wx.BoxSizer(wx.HORIZONTAL)
        sizerKeyFrame.Add(self._bnPreKeyFrame, 0, wx.ALL, border = 5)
        sizerKeyFrame.Add(self._bnNextKeyFrame, 0, wx.ALL, border = 5)
        sizerKeyFrame.Add(self._bnSetKeyFrame, 0, wx.ALL, border = 5)
        sizerKeyFrame.Add(self._bnRemoveKeyFrame, 0, wx.ALL, border = 5)
        
        sizerParam = wx.BoxSizer(wx.HORIZONTAL)
        sizerParam.Add(self._color, 0, wx.ALL, border = 5)
        sizerParam.Add(self._editParam1, 0, wx.ALL, border = 5)
        sizerParam.Add(self._editParam2, 0, wx.ALL, border = 5)
        sizerParam.Add(self._editParam3, 0, wx.ALL, border = 5)
                        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self._staticModifierType, 0, wx.LEFT|wx.TOP|wx.BOTTOM, border = 20)
        sizer.Add(self._slider, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, border = 5)
        sizer.Add(self._ticksWin, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, border = 5)
        sizer.Add(sizerKeyFrame, 0, wx.ALL|wx.EXPAND, border = 5)
        sizer.Add(sizerParam, 0, wx.ALL|wx.EXPAND, border = 5)
        self.SetSizer(sizer)
        
        self._ticksWin.Bind(wx.EVT_SIZE, self.__OnTicksWinResized)
        self.Bind(wx.EVT_BUTTON, self.__OnBnClickSetKeyFrame, self._bnSetKeyFrame)
        self.Bind(wx.EVT_PAINT, self.__OnPaint)
        self.Bind(wx.EVT_SCROLL, self.__OnScrollSlider, self._slider)

        self._tickList = []
        self._valueDict = {}
        
        self._modifierRef = None
        
    def SetModifier(self, modifier):
        self._modifierRef = weakref.ref(modifier)
        self._staticModifierType.SetLabel(modifier._name)
        self._tickList = []
        self._valueDict = {}
        self.__UpdateUI()
                
    def __OnTicksWinResized(self, e):
        size = self._ticksWin.GetClientSize()
        self._bmpBuffer = wx.EmptyBitmap(max(1, size.width), max(1, size.height))
        self.__RefreshTicks()

    def __UpdateUI(self):
        self.__OnUpdateParamUI()
        self.__OnUpdateKeyFrame()
        self.__RefreshTicks()
        self.Refresh()
        
    def __OnUpdateParam(self):
        try:
            modifier = self._modifierRef()
            emitter = modifier._emitterRef()
        except:
            return
            
        pos = self._slider.GetValue()
        value = modifier.GetValue(pos)
        if modifier._type == ParticleEmitter.PMT_COLOR:
            ret, color = value
            if not ret:
                color = ParticleEmitter.GetColor(emitter.GetCoreHandle())
                
            wxColor = DWORD_TO_WXCOLOR(color)
            self._color.SetColour(wxColor)
        elif modifier._type == ParticleEmitter.PMT_TEXTURE_FRAME:
            ret, frame = value
            if not ret:
                frame = ParticleEmitter.GetTextureFrame(emitter.GetCoreHandle())
            
            self._editParam1.SetValue(str(frame))
        elif modifier._type == ParticleEmitter.PMT_DIRECTION_FORCE:
            pass
        elif modifier._type == ParticleEmitter.PMT_SIZE:
            ret, w, h = value
            if not ret:
                w, h = ParticleEmitter.GetParticleSizeMax(emitter.GetCoreHandle())
                
            self._editParam1.SetValue(str(w))
            self._editParam2.SetValue(str(h))
            
    def __OnUpdateParamUI(self):
        try:
            modifier = self._modifierRef()
        except:
            return
                    
        if modifier._type == ParticleEmitter.PMT_COLOR:
            self._color.Enable(True)
            self._editParam1.Enable(False)
            self._editParam2.Enable(False)
            self._editParam3.Enable(False)
            self.__OnUpdateParam()
        elif modifier._type == ParticleEmitter.PMT_TEXTURE_FRAME:
            self._color.Enable(False)
            self._editParam1.Enable(True)
            self._editParam2.Enable(False)
            self._editParam3.Enable(False)
            self.__OnUpdateParam()
        elif modifier._type == ParticleEmitter.PMT_DIRECTION_FORCE:
            self._color.Enable(False)
            self._editParam1.Enable(True)
            self._editParam2.Enable(True)
            self._editParam3.Enable(True)
            self.__OnUpdateParam()
        elif modifier._type == ParticleEmitter.PMT_SIZE:
            self._color.Enable(False)
            self._editParam1.Enable(True)
            self._editParam2.Enable(True)
            self._editParam3.Enable(False)
            self.__OnUpdateParam()              
                      
    def __RefreshTicks(self):
        dc = wx.BufferedDC(wx.ClientDC(self._ticksWin), self._bmpBuffer)
        dc.SetBackground(wx.Brush(wx.BLACK))
        dc.Clear()
        
        dc.BeginDrawing()
        pen = wx.Pen(wx.WHITE, 1, wx.SOLID)
        dc.SetPen(pen)
       
        ticksWinSize = self._ticksWin.GetClientSize()
        left = 11
        width = ticksWinSize.width - left * 2
        life = self._slider.GetMax()
        for i in self._tickList:
            x = float(life - i) / life * width + left
            dc.DrawLine(x, 0, x, 15)
        dc.EndDrawing()
                
    def __OnPaint(self, e):
        dc = wx.BufferedPaintDC(self._ticksWin, self._bmpBuffer)
        e.Skip()        
            
    def AddKeyFrame(self, life, value):
        if self._tickList.count(life):
            self._valueDict[life] = value
            return
        self._tickList.append(life)
        self._tickList.sort(reverse = True)
        self._valueDict[life] = value
        self.__RefreshTicks()
        
    def __OnBnClickSetKeyFrame(self, e):
        try:
            modifier = self._modifierRef()
        except:
            return
                    
        try:
            life = self._slider.GetValue()
            if modifier._type == ParticleEmitter.PMT_COLOR:
                color = self._color.GetColour()
                modifier.SetKeyFrame(life, color)
                self.AddKeyFrame(life, WXCOLOR_TO_DWORD(color))
                self.__RefreshTicks()
            elif modifier._type == ParticleEmitter.PMT_TEXTURE_FRAME:
                frame = int(self._editParam1.GetValue())
                modifier.SetKeyFrame(life, frame)
                self.AddKeyFrame(life, frame)
                self.__RefreshTicks()
            elif modifier._type == ParticleEmitter.PMT_DIRECTION_FORCE:
                self.__RefreshTicks()
            elif modifier._type == ParticleEmitter.PMT_SIZE:
                w = float(self._editParam1.GetValue())
                h = float(self._editParam2.GetValue())
                modifier.SetKeyFrame(life, (w, h))
                self.AddKeyFrame(life, (w, h))
                self.__RefreshTicks()
            elif modifier._type == ParticleEmitter.PMT_VELOCITY_PERCENT:
                self.__RefreshTicks()
                    
        except:
            SHOW_TRACE()
            
    def __OnScrollSlider(self, e):
        self.__OnUpdateParamUI()         

    def __OnUpdateKeyFrame(self):
        try:
            modifier = self._modifierRef()
        except:
            return
                    
        keyFrameCnt = modifier.GetKeyFrameCount()
        for i in xrange(0, keyFrameCnt):
            value = modifier.GetKeyFrameByIndex(i)
            if value[0]:
                self.AddKeyFrame(value[1], value[2:])
        
